package model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import exceptios.CantidadJugadoresPorClubExcption;
import exceptios.CantidadJugadoresPorEquipoException;
import exceptios.CantidadJugadoresPorPuestoException;
import exceptios.CostoEquipoException;
import exceptios.ValidarEquipoException;


public class Equipo {
 
	public static final int CANTIDAD_JUGADORES_TOTAL_MIN = 6;
	
	public static final int CANTIDAD_JUGADORES_MISMO_CLUB_MAX = 6;
	
	public static final int CANTIDAD_JUGADORES_MISMA_POS_MIN = 2;
	
	public static final int COSTO_TOTAL_MAX = 100000;
	
	private String nombre;
	 
	private int costoTotal;
	 
	private int cantJugadores;
	 
	private List<Jugador> formacion;
	 
	private Participante participante;
	 
	//private Jugador[] jugador;
	
	public Equipo(){
		this.formacion = new ArrayList<Jugador>();
	}
	
	public void agregarJugador(Jugador jugador) {
		formacion.add(jugador);
	}
	 
	public void cambiarJugador(Jugador jugadorEntra, Jugador jugadorSale) {
	 
	}
	 
	public void quitarJugador(Jugador jugador) {
	 
	}

	public int getCantJugadores() {
		return cantJugadores;
	}

	public void setCantJugadores(int cantJugadores) {
		this.cantJugadores = cantJugadores;
	}

	public int getCostoTotal() {
		return costoTotal;
	}

	public void setCostoTotal(int costoTotal) {
		this.costoTotal = costoTotal;
	}

	public List getFormacion() {
		return formacion;
	}

	public void setFormacion(List formacion) {
		this.formacion = formacion;
	}

//	public Jugador[] getJugador() {
//		return jugador;
//	}
//
//	public void setJugador(Jugador[] jugador) {
//		this.jugador = jugador;
//	}

	public String getNombre() {
		return nombre;
	}

	public void setNombre(String nombre) {
		this.nombre = nombre;
	}

	public Participante getParticipante() {
		return participante;
	}

	public void setParticipante(Participante participante) {
		this.participante = participante;
	}
	 
	public boolean validarEquipo() throws ValidarEquipoException{
		boolean valido = true;
		
		// regla de cantidad de jugadores por club
		if (!validarCantJugadoresDeUnClub()){
			ValidarEquipoException ex = new CantidadJugadoresPorClubExcption();
			valido = false;
			throw ex;
		}
		
		// regla de cantidad de jugadores por puesto
		if ( !validarCantJugadoresPorPosicion()){
			ValidarEquipoException ex = new CantidadJugadoresPorPuestoException();
			valido = false;
			throw ex;
		}
		
		// regla del costo total del equipo
		if ( !validarCostoEquipo()) {
			ValidarEquipoException ex = new CostoEquipoException();
			valido = false;
			throw ex;
		}
		
		// regla de la cantidad de jugadores
		if ( !validarCantidadMinimaJugadoresPorEquipo()) {
			ValidarEquipoException ex = new CantidadJugadoresPorEquipoException();
			valido = false;
			throw ex;
		}

		return valido;
	}
	
	
	/**
	 * 
	 * @return true indica que no se eligio mas del maximo de jugadores de un mismo club
	 */
	@SuppressWarnings("unchecked")
	public boolean validarCantJugadoresDeUnClub(){
		
		Collection<Jugador> formacion = this.getFormacion();
		HashMap<Club, Integer> clubs = new HashMap<Club, Integer>();
		Club unClub;
		int cantJugadores;
		
		//Cuento la cantidad de jugadores de cada club
		for (Object unJugador : formacion) {
			unClub = ((Jugador)unJugador).getClub();
			
			//Si el Club de este jugador aun no fue elegido, lo cuento por primera vez
			if(!clubs.containsKey(unClub)){
				clubs.put(unClub, 1);
			}else{
				//obtengo la cantidad de jugadores de este club
				cantJugadores = clubs.get(unClub).intValue();
				
				//incremento en uno y guardo la nueva cantidad de jugadores de ese club
				clubs.put(unClub, ++cantJugadores);
			}
		}
		
		//Recorro el mapa de club elegidos y veo si alguno tiene mas de la cantidad maxima permitida
		boolean superoElLimite = false;
		Collection<Integer> cantidades = clubs.values();//Obtengo todas las cantidades
		for (Iterator<Integer> iterator = cantidades.iterator(); iterator.hasNext() && !superoElLimite;) {
			Integer integer = (Integer) iterator.next();
			if(integer.intValue() > Equipo.CANTIDAD_JUGADORES_MISMO_CLUB_MAX){
				superoElLimite = true;
			}			
		}
				
		//si no supera el limite debe retornar true
		return !superoElLimite;
	}

	
	/**
	 * 
	 * @return true indica que no se eligio mas del maximo de jugadores de un mismo club
	 */
	@SuppressWarnings("unchecked")
	public boolean validarCantJugadoresPorPosicion(){
		
		Collection<Jugador> formacion 			= this.getFormacion();
		HashMap<Posicion, Integer> posiciones 	= new HashMap<Posicion, Integer>();
		Posicion unaPosicion;
		int cantJugadores;
		
		//Cuento la cantidad de jugadores en cada posicion
		for (Object unJugador : formacion) {
			unaPosicion = ((Jugador)unJugador).getPosicion();
			
			//Si la posicion de este jugador aun no fue elegida, la cuento por primera vez
			if(!posiciones.containsKey(unaPosicion)){
				posiciones.put(unaPosicion, 1);
			}else{
				//obtengo la cantidad de jugadores en esa posicion
				cantJugadores = posiciones.get(unaPosicion).intValue();
				
				//incremento en uno y guardo la nueva cantidad de jugadores de ese club
				posiciones.put(unaPosicion, ++cantJugadores);
			}
		}
		
		//Recorro el mapa de posiciones elegidas y veo si alguno tiene menos de la cantidad minima permitida
		boolean superoElLimite = true;
		Collection<Integer> cantidades = posiciones.values();//Obtengo todas las cantidades
		for (Iterator<Integer> iterator = cantidades.iterator(); iterator.hasNext() && superoElLimite;) {
			Integer integer = (Integer) iterator.next();
			if(integer.intValue() < Equipo.CANTIDAD_JUGADORES_MISMA_POS_MIN){
				superoElLimite = false;
			}			
		}
				
		return superoElLimite;
	}
	
	public boolean validarCostoEquipo(){
		return (this.getCostoTotal() <= Equipo.COSTO_TOTAL_MAX);
	}
	
	
	/**
	 * @return Si la cantidad de Jugadores que contiene la formacion no alcanza la minima dara false.
	 */
	public boolean validarCantidadMinimaJugadoresPorEquipo(){		
		return (formacion.size() >= Equipo.CANTIDAD_JUGADORES_TOTAL_MIN);
	}
	 
}
 
